import { SyncHook, AsyncParallelHook, SyncBailHook, SyncWaterfallHook, AsyncSeriesHook } from 'tapable'

class BigCar {
    constructor(){
        this.pluginMap = {}
        this.hooks = {
            // 计算费用
            calculateCost: new AsyncSeriesHook(['distance'])
        }
    }
    use (plugin) {
        // 初始化插件
        const pluginRunTime = new plugin(this)
        // 添加插件名称
        pluginRunTime.pluginName = pluginRunTime.constructor.name
        // 装载插件到集合
        this.pluginMap[pluginRunTime.pluginName] = pluginRunTime

        this._bindingHooks(pluginRunTime)
    }
    _bindingHooks (plugin) {
        Object.keys(this.hooks).forEach(hookName => {
            const hook = plugin[hookName]
            if (hook) {
                // tapPromise 方法来自初始化AsyncSeriesHook
                this.hooks[hookName].tapPromise(plugin.pluginName, function () {
                    // apply调用插件方法，并传递参数
                    const result = hook.apply(plugin, [...arguments])
                    // hook 兼容非 Promise 返回值
                    return result instanceof Promise ? result : Promise.resolve(result);
                })
            }
        })
    }
}

export default BigCar